/*
 * Licensee agrees that the example code provided to Licensee has been developed and released by Bosch solely as an example to be used as a potential reference for application development by Licensee.
 * Fitness and suitability of the example code for any use within application developed by Licensee need to be verified by Licensee on its own authority by taking appropriate state of the art actions and measures (e.g. by means of quality assurance measures).
 * Licensee shall be responsible for conducting the development of its applications as well as integration of parts of the example code into such applications, taking into account the state of the art of technology and any statutory regulations and provisions applicable for such applications. Compliance with the functional system requirements and testing there of (including validation of information/data security aspects and functional safety) and release shall be solely incumbent upon Licensee.
 * For the avoidance of doubt, Licensee shall be responsible and fully liable for the applications and any distribution of such applications into the market.
 *
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     (1) Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *     (2) Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in
 *     the documentation and/or other materials provided with the
 *     distribution.
 *
 *     (3)The name of the author may not be used to
 *     endorse or promote products derived from this software without
 *     specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 *  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 *  DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
 *  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 *  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 *  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 *  STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 *  IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 */
/*----------------------------------------------------------------------------*/

/**
 * @ingroup APPS_LIST
 *
 * @defgroup SEND_ACCELEROMETER_DATA_OVER_UDP_AND_BLE SendAccelDataOverUdpandBle
 * @{
 *
 * @brief Demo application of Transmitting BMA280 Accelerometer data on BLE(Bluetooth Low Energy) and UDP every configured interval (#APP_CONTROLLER_TX_DELAY)
 *
 * @details This example demonstrates how to read sensor values from the BMA280 Acceleration sensor and streams them over Bluetooth Low Energy via custom Bi-Directional Service.<br>
 * Either use your Android or iOS mobile phone (see [Android](https://play.google.com/store/apps/details?id=com.macdom.ble.blescanner&hl=en) or
 * [iOS](https://itunes.apple.com/in/app/lightblue-explorer-bluetooth-low-energy/id557428110?mt=8) App Store) to connect to XDK and receive the data.
 * Send command <b>start (HEX: 0x7374617274)</b>  to XDK via Bluetooth Low Energy, so that streaming of data begins.
 * To stop the streaming send command <b>end (HEX: 656e64)</b>
 *
 * This Application enables the bi-directional service in ble and sends Accelerometer Data over ble and UDP. <br>
 * <b> Bi-Directional Service : </b>
 *
 *  Service             |  Characteristic                |         Attribute-Type             |               UUID                   |
 * ---------------------|--------------------------------|------------------------------------|--------------------------------------|
 * BidirectionalService |    NA                          |         uint8_t                    | b9e875c0-1cfa-11e6-b797-0002a5d5c51b |
 * NA                   |    Rx                          |         uint8_t X[20]              | 0c68d100-266f-11e6-b388-0002a5d5c51b |
 * NA                   |    Tx                          |         uint8_t X[20]              | 1ed9e2c0-266f-11e6-850b-0002a5d5c51b |
 *
 * @file
 **/

/* module includes ********************************************************** */

/* own header files */
#include "XdkAppInfo.h"
#undef BCDS_MODULE_ID  /* Module ID define before including Basics package*/
#define BCDS_MODULE_ID XDK_APP_MODULE_ID_APP_CONTROLLER

/* own header files */
#include "AppController.h"

/* system header files */
#include <stdio.h>

/* additional interface header files */
#include "XDK_UDP.h"
#include "XDK_WLAN.h"
#include "XDK_BLE.h"
#include "XDK_Sensor.h"
#include "BCDS_BSP_Board.h"
#include "BCDS_WlanNetworkConfig.h"
#include "BCDS_CmdProcessor.h"
#include "XDK_Utils.h"
#include "FreeRTOS.h"
#include "task.h"
#include "BCDS_Assert.h"
#include "XDK_LED.h"
#include "XDK_Storage.h"
#include "XDK_Button.h"
#include "BCDS_WlanConnect.h"
#include "timers.h"
#include "semphr.h"
#include "AdcCentralConfig.h"
#include "wlan.h"

#define XDK_ASSERT(x) { if (!x) { printf("ASSERT at %s,%d", __FUNCTION__, __LINE__); while(1);}}

/* constant definitions ***************************************************** */

#define APP_CONTROLLER_BLE_SEND_TIMEOUT_IN_MS       UINT32_C(1000)/**< Timeout for BLE send */

#define APP_CONTROLLER_BLE_START_TRIGGER            UINT32_C(1)/**< BLE start command send application logic */

#define APP_CONTROLLER_BLE_END_TRIGGER              UINT32_C(0)/**< BLE end command send application logic */

#define APP_CONTROLLER_BLE_TX_LEN                   UINT8_C(20)/**< Size of accelerometer complete payload in bytes with spaces in-between the axis values and NULL terminator */

#define APP_CONTROLLER_TX_AXIS_COUNT                UINT8_C(3)/**< Number of accelerometer axis (x, y & z) */

#define APP_TEMPERATURE_OFFSET_CORRECTION               (-3459)/**< Macro for static temperature offset correction. Self heating, temperature correction factor */

#define APP_CONTROLLER_BLE_RX_BUFFER_SIZE          UINT8_C(20)/**< Size of BLE receive buffer*/

#define NOISE_SENSOR_DATA_VOLTS_TO_MILLIVOLTS               1000.0f

#define MAX_LEN_WLAN_SSID              32
#define MAX_LEN_WLAN_PASSWD            32

#define BUFFER_SIZE                 UINT16_C(512)
#define SINGLE_BLOCK                UINT8_C(1)      /**< SD- Card Single block write or read */
#define DRIVE_ZERO                  UINT8_C(0)      /**< SD Card Drive 0 location */
#define SECTOR_VALUE                UINT8_C(6)      /**< SDC Disk sector value */
#define SINGLE_SECTOR_LEN           UINT32_C(512)   /**< Single sector size in SDcard */
#define WIFI_CFG_FILE_READ_BUFFER 2024
#define WIFI_CONFIG_FILE_NAME                           ".pacom_config.ini"

#define NOISE_RMS_ADC_SAMPLES                               UINT32_C(30)
#define NOISE_RMS_AVG_RANGE_IN_MV                           0.005f
#define NOISE_SAMPLING_FREQUENCY                            (20000UL)            /**< ADC sampling frequency in hertz (Hz)*/

typedef struct te_xdk_datas {
	uint8_t rev[2];
	uint8_t Len;
	uint8_t Flag;
	Sensor_Value_T Sensors;
} XDK_DATA_T;

typedef struct te_xdk_attrib {
	uint8_t Len;
	uint8_t Flag;
	uint8_t LEDs;
	uint8_t Buttons;
	uint32_t BatVol;
	uint8_t BleMac[6];
//uint8_t WifiMac[6];
} XDK_ATTRIB_T;

/* Prototype declare ********************************************************** */
static void AppControllerBleDataRxCB(uint8_t *rxBuffer, uint8_t rxDataLength,
		void * param);
static Retcode_T WifiConfigFromSD(void);
static void Button1Callback(ButtonEvent_T buttonEvent);
static void Button2Callback(ButtonEvent_T buttonEvent);

/* local variables ********************************************************** */
static WLAN_Setup_T WLANSetupInfo = { .IsEnterprise = false, .IsHostPgmEnabled =
false, .SSID = ALT_WLAN_SSID_DEFAULT, .Username = WLAN_PASSWORD_DEFAULT, .Password =
WLAN_PASSWORD_DEFAULT, .IsStatic = WLAN_STATIC_IP_DEFAULT, .IpAddr =
WLAN_IP_ADDR_DEFAULT, .GwAddr = WLAN_GW_ADDR_DEFAULT, .DnsAddr =
WLAN_DNS_ADDR_DEFAULT, .Mask = WLAN_MASK_DEFAULT, };/**< WLAN setup parameters */

static char cfgWlanSsid[MAX_LEN_WLAN_SSID];
static char cfgAltWlanSsid[MAX_LEN_WLAN_SSID];
static char cfgWlanPswd[MAX_LEN_WLAN_PASSWD];
static uint32_t cfgUdpIp;
static int16_t cfgUdpPort;
static bool bcfgValid = false;
static bool pacomCfgValid = false;
static uint8_t cfgLogLvl = 8;
char bleDeviceName[]=APP_CONTROLLER_BLE_DEVICE_NAME;

/* local module global variable declarations */
Storage_Setup_T StorageSetupInfo = { .SDCard = true, .WiFiFileSystem = false };/**< Storage setup parameters */

/**
 * @brief This is the BLE data receive callback function
 *
 * @param[in]   rxBuffer
 * pointer to the received data buffer
 *
 * @param[in]   rxDataLength
 * Length of the received data
 *
 * @param[in]   param
 * unused
 *
 * @note Do not perform any heavy processing within this function and return ASAP.
 */
static BLE_Setup_T BLESetupInfo = {
		.DeviceName = bleDeviceName, .IsMacAddrConfigured =
		false, .MacAddr = 0UL, .Service = BLE_BCDS_BIDIRECTIONAL_SERVICE,
		.IsDeviceCharacteristicEnabled = false, .CharacteristicValue = {
				.ModelNumber = NULL, .Manufacturer = NULL, .SoftwareRevision =
				NULL }, .DataRxCB = AppControllerBleDataRxCB,
		.CustomServiceRegistryCB = NULL, };/**< BLE setup parameters */

static Sensor_Setup_T SensorSetup = { .CmdProcessorHandle = NULL, .Enable = {
		.Accel = true, .Mag = true, .Gyro = true, .Humidity = true,
		.Temp = true, .Pressure = true, .Light = true, .Noise = false, },
		.Config = { .Accel = { .Type = SENSOR_ACCEL_BMA280, .IsRawData = false,
				.IsInteruptEnabled = false, .Callback = NULL, }, .Gyro = {
				.Type = SENSOR_GYRO_BMG160, .IsRawData = false, }, .Mag = {
				.IsRawData = false }, .Light = { .IsInteruptEnabled = false,
				.Callback = NULL, }, .Temp = { .OffsetCorrection =
		APP_TEMPERATURE_OFFSET_CORRECTION, } }, };/**< Sensor setup parameters */

/* local variables ********************************************************** */

static Button_Setup_T ButtonSetup = { .CmdProcessorHandle = NULL,
		.InternalButton1isEnabled = true, .InternalButton2isEnabled = true,
		.InternalButton1Callback = Button1Callback, .InternalButton2Callback =
				Button2Callback, };
/**< Button setup parameters */

static CmdProcessor_T * AppCmdProcessor;/**< Handle to store the main Command processor handle to be used by run-time event driven threads */

static xTaskHandle WifiConnectHandle = NULL;
static xTaskHandle AppControllerHandle = NULL;/**< OS thread handle for Application controller to be used by run-time blocking threads */
static xTaskHandle TaskUdpRcvHandle = NULL;/**< OS thread handle for Application controller to be used by run-time blocking threads */
static xTaskHandle NoiseSensorHandle = NULL;/**< OS thread handle for noise sensor to be used by run-time blocking threads */

static volatile float NoiseRmsVoltage = 0.0f;

static bool AppControllerBleTransmitPayload = false; /**< Boolean representing if BLE needs to be streamed. Validate the repeated start flag */

static XDK_ATTRIB_T xdkAttrib;
static XDK_DATA_T xdkData;
static TimerHandle_t tmrSensorFire;
static bool notifyAttribOnly = false;
static xSemaphoreHandle xSemFire = NULL;
static uint32_t noiseMVolt = 0;

Retcode_T AppHttpSetup( CmdProcessor_T * appCmdProcessor);

/* global variables ********************************************************* */

/* inline functions ********************************************************* */

/* local functions ********************************************************** */

/**
 * @brief This will validate the WLAN network connectivity
 *
 * Currently, upon abrupt disconnection the event from the WiFi chip is not
 * propagated / notified to the application. Until then, we manually validate
 * prior to ever HTTP Rest Client POST/GET cycle to make sure that the possibility
 * of software break is reduced. We check if the IP is valid to validate the same.
 * !!! need reconnect wifi few senconds later!!!!
 */
Retcode_T AppControllerValidateWLANConnectivity(void) {
	Retcode_T retcode = RETCODE_OK;
	WlanNetworkConfig_IpStatus_T ipStatus = WLANNWCNF_IPSTATUS_IP_NOTAQRD;
	WlanNetworkConfig_IpSettings_T ipAddressOnGetStatus;

	ipStatus = WlanNetworkConfig_GetIpStatus();
	if (ipStatus == WLANNWCNF_IPSTATUS_IPV4_AQRD) {
		retcode = WlanNetworkConfig_GetIpSettings(&ipAddressOnGetStatus);
		if ((RETCODE_OK == retcode)
				&& (UINT32_C(0) == (ipAddressOnGetStatus.ipV4))) {
			/* Our IP configuration is corrupted somehow in this case. No use in proceeding further. */
			retcode = RETCODE(RETCODE_SEVERITY_ERROR,
					RETCODE_NODE_IPV4_IS_CORRUPTED);
		}
	} else {
		/* Our network connection is lost. No use in proceeding further. */
		retcode = RETCODE(RETCODE_SEVERITY_ERROR,
				RETCODE_NODE_WLAN_CONNECTION_IS_LOST);
	}
	return retcode;
}

/**
 * @brief   This will send start or stop message based on input parameter
 *
 *  @param [in]  param1
 *  Unused, Reserved for future use
 *
 *  @param [in]  param2
 *  Differentiates start and stop command.
 *  APP_CONTROLLER_BLE_START_PAYLOAD for start.
 *  APP_CONTROLLER_BLE_END_PAYLOAD for stop.
 */
static void AppControllerBleStartOrEndMsgSend(void * param1, uint32_t param2) {
	BCDS_UNUSED(param1);

	Retcode_T retcode = RETCODE_OK;

	if (param2 == APP_CONTROLLER_BLE_START_TRIGGER) {
		retcode = BLE_SendData(((uint8_t*) APP_CONTROLLER_BLE_START_PAYLOAD),
				((uint8_t) sizeof(APP_CONTROLLER_BLE_START_PAYLOAD) - 1), NULL,
				APP_CONTROLLER_BLE_SEND_TIMEOUT_IN_MS);
	} else if (param2 == APP_CONTROLLER_BLE_END_TRIGGER) {
		retcode = BLE_SendData(((uint8_t*) APP_CONTROLLER_BLE_END_PAYLOAD),
				((uint8_t) sizeof(APP_CONTROLLER_BLE_END_PAYLOAD) - 1), NULL,
				APP_CONTROLLER_BLE_SEND_TIMEOUT_IN_MS);
	} else {
		/* Do nothing */;
	}
	if (RETCODE_OK != retcode) {
		Retcode_RaiseError(retcode);
	}
}

/**
 * @brief Callback function called on data reception over BLE
 *
 * @param [in]  rxBuffer : Buffer in which received data to be stored.
 *
 * @param [in]  rxDataLength : Length of received data.
 * @param [in]  param
 * Unused
 */
static void AppControllerBleDataRxCB(uint8_t *rxBuffer, uint8_t rxDataLength,
		void * param) {
	BCDS_UNUSED(param);
	BCDS_UNUSED(rxDataLength);
	uint32_t itmp;
	Retcode_T retcode = RETCODE_OK;
	uint8_t bleReceiveBuff[APP_CONTROLLER_BLE_RX_BUFFER_SIZE];
	memset(bleReceiveBuff, 0, sizeof(bleReceiveBuff));
	memcpy(bleReceiveBuff, rxBuffer, rxDataLength);
	if (cfgLogLvl < 7) {
		for (itmp = 0; itmp < rxDataLength; itmp++) {
			printf("%02X", rxBuffer[itmp]);
		}
	}
	printf("\n");
	/* validate received data */
	if ((0UL == strcmp((const char *) bleReceiveBuff,
	APP_CONTROLLER_BLE_START_ID))
			&& (false == AppControllerBleTransmitPayload)) {
		retcode = CmdProcessor_Enqueue(AppCmdProcessor,
				AppControllerBleStartOrEndMsgSend, NULL,
				APP_CONTROLLER_BLE_START_TRIGGER);
		AppControllerBleTransmitPayload = true;
	} else if ((0UL
			== strcmp((const char *) bleReceiveBuff, APP_CONTROLLER_BLE_END_ID))
			&& (true == AppControllerBleTransmitPayload)) {
		AppControllerBleTransmitPayload = false;
		retcode = CmdProcessor_Enqueue(AppCmdProcessor,
				AppControllerBleStartOrEndMsgSend, NULL,
				APP_CONTROLLER_BLE_END_TRIGGER);
	} else if (0UL == memcmp((const char *) bleReceiveBuff, "udp=", 4)) {
		if ( RETCODE_OK
				== Utils_ConvertIpStringToNumber((const char*)(&bleReceiveBuff[4]), &itmp)) { //udp=192.168.1.88
			cfgUdpIp = itmp;
			printf("udp_ip= [%X]\n", (int) cfgUdpIp);
		}
	} else if (0UL == memcmp((const char *) bleReceiveBuff, "loglvl=", 7)) {
		if ((itmp = (uint32_t) atoi((const char *)(&bleReceiveBuff[7]))) != 0) {
			cfgLogLvl = itmp;
			printf("loglvl= [%X]\n", (int) cfgLogLvl);
		}
	} else {
		;/* Do nothing since we are not interested in garbage */
	}

	if (RETCODE_OK != retcode) {
		Retcode_RaiseError(retcode);
	}
}


// led_orange:on , silence mode
// ?led_orange:on , acknowledge mode with ? mark
Retcode_T UdpCmdProc(char * cmd, uint16_t *len, void * param) {
	Retcode_T retcode = RETCODE_OK;
	cmd[(*len)] = 0;
	strupr(cmd);
	LED_T ledidx = LED_INBUILT_INVALID;
	char *ps = strchr(cmd, ':');
	if (ps == NULL)
		return RETCODE_INVALID_PARAM;

	int para = ps - cmd;

	if (0 == memcmp(cmd, "LED_RED:", para)) {
		ledidx = LED_INBUILT_RED;
	} else if (0 == memcmp(cmd, "LED_YELLOW:", para)) {
		ledidx = LED_INBUILT_YELLOW;
	} else if (0 == memcmp(cmd, "LED_ORANGE:", para)) {
		ledidx = LED_INBUILT_ORANGE;
	} else {
		return RETCODE_NOT_SUPPORTED;
	}

	if (0 == memcmp(ps + 1, "ON", 2)) {
		LED_On(ledidx);
	} else if (0 == memcmp(ps + 1, "OFF", 3)) {
		LED_Off(ledidx);
	} else
		retcode = RETCODE_NOT_SUPPORTED;

	if (RETCODE_OK == retcode) {
		notifyAttribOnly = true;
		xSemaphoreGive(xSemFire);
	}

	return retcode;
}

Retcode_T UdpCmdProcEntry(void * buf, uint16_t *len, void * param) {
	printf("recv cmd =%s\n", (char *) buf);
	int silence = (*(char *) buf == '?') ? 0 : 1;
	Retcode_T ret = UdpCmdProc((silence) ? buf : buf + 1, len, param);
	if (silence)
		return RETCODE_OK;
	switch (ret) {
	case RETCODE_INVALID_PARAM:
		strcpy((char *) buf, "invalid command format");
		break;
	case RETCODE_NOT_SUPPORTED:
		strcpy(buf, "unkown command");
		break;
	case RETCODE_OK:
		strcpy(buf, "ok");
		break;
	default:
		strcpy(buf, "fail");
	}
	*len = strlen((char*) buf);
	return RETCODE_FIRST_CUSTOM_CODE;
}

static void UpdRcvSvr(void * pvParameters) {
	BCDS_UNUSED(pvParameters);
	printf("\ntask udp listen at %d\n", cfgUdpPort + 1);
	char buff[256];
	memset(buff, 0, sizeof(buff));
	//UDP_Recvx();
	UDP_Recv(cfgUdpPort + 1, buff, sizeof(buff), UdpCmdProcEntry, NULL);
}

static uint8_t GetLedStatus(LED_T led) {
	uint8_t ledst = 0;
	if ( APP_LED_INDICATE_ONLINE != led)
		LED_Status(led, &ledst);
	return ledst;
}

static int AppGetXdkAttrib() {
	static int divd = 0;

	uint8_t LedStat = 0;
	LedStat |= GetLedStatus(LED_INBUILT_RED);
	LedStat |= GetLedStatus(LED_INBUILT_YELLOW) << 1;
	LedStat |= GetLedStatus(LED_INBUILT_ORANGE) << 2;

	uint32_t batVol = 0;
	BatteryMonitor_MeasureSignal(&batVol);

	if (notifyAttribOnly || divd-- == 0) {
		divd = APP_ATTRIB_REPT_DELAY;
	} else {
		int volDiff = xdkAttrib.BatVol - batVol;
		volDiff = ABS(volDiff);

		if (volDiff < 150 || xdkAttrib.LEDs == LedStat)
			return RETCODE_OUT_OF_RESOURCES;
	}

	//printf("BAT: %d, LED:%X\n", (int)batVol, LedStat);
	xdkAttrib.BatVol = batVol;
	xdkAttrib.LEDs = LedStat;

	return RETCODE_OK;
}

void vTimerCallback(TimerHandle_t xTimer) {
	BCDS_UNUSED(xTimer);
	notifyAttribOnly = false;
	xSemaphoreGive(xSemFire);
}

static void AppControllerFire(void* pvParameters) {
	BCDS_UNUSED(pvParameters);

	xSemFire = xSemaphoreCreateCounting(100, 0);
	configASSERT(xSemFire!=NULL);
	tmrSensorFire = xTimerCreate("tmrSensorFire", APP_CONTROLLER_TX_DELAY,
	pdTRUE, (void *) 0, vTimerCallback);
	configASSERT(tmrSensorFire != NULL);
	configASSERT(xTimerStart( tmrSensorFire, 0 ) == pdPASS);

	printf("Udp info:ip[%d.%d.%d.%d:%d]\n",(int)(cfgUdpIp&0XFF), (int)((cfgUdpIp>>8)&0xFF),  (int)((cfgUdpIp>>16)&0xFF),(int)(cfgUdpIp>>24),  (int)cfgUdpPort);
	memset(&xdkData.Sensors, 0x00, sizeof(Sensor_Value_T));

	while (1) {
		xSemaphoreTake(xSemFire, portMAX_DELAY);
		LED_Toggle(APP_LED_INDICATE_ONLINE);

		Retcode_T retcode = RETCODE_OK;
		Retcode_T retcodeUdp = RETCODE_OK;
		int16_t handle = 0;
		Sensor_Value_T Sensors;
		if (Sensor_GetData(&Sensors) != RETCODE_OK)
			continue;
		xdkData.Sensors = Sensors;

		//for get noise sensor data
		xdkData.Sensors.Noise = (NoiseRmsVoltage
				* NOISE_SENSOR_DATA_VOLTS_TO_MILLIVOLTS);
		noiseMVolt = (uint32_t)xdkData.Sensors.Noise;

		bool bRptAttr = (RETCODE_OK == AppGetXdkAttrib());

		/* Check whether the WLAN network connection is available */
		if (pacomCfgValid && RETCODE_OK == AppControllerValidateWLANConnectivity()) {
			retcodeUdp = UDP_Open(&handle);
			if (RETCODE_OK == retcodeUdp) {
				if (bRptAttr) { //report attribute
					retcodeUdp = UDP_Send(handle, cfgUdpIp, cfgUdpPort,
							(uint8_t *) &xdkAttrib, sizeof(xdkAttrib));
					if (cfgLogLvl < 8)
						printf("send attrib to [%d.%d.%d.%d]\n",(int)(cfgUdpIp&0XFF), (int)((cfgUdpIp>>8)&0xFF),  (int)((cfgUdpIp>>16)&0xFF), (int)(cfgUdpIp>>24) );
				}

				if (!notifyAttribOnly) {
					xdkData.Flag = 'S';
					xdkData.Len = sizeof(xdkData) - 2;
					retcodeUdp = UDP_Send(handle, cfgUdpIp, cfgUdpPort,
							(uint8_t *) &xdkData.Len, xdkData.Len);
					if (cfgLogLvl <= 8)
						printf("%d/temp:[%u],  Him:[%d] , Light:[%d], Noise:[%f]\n",
								cfgLogLvl, (int)(xdkData.Sensors.Temp),
								(int)xdkData.Sensors.RH, (int)xdkData.Sensors.Light, xdkData.Sensors.Noise);
				}
			}
			UDP_Close(handle);
			if (RETCODE_OK != retcodeUdp) {
				Retcode_RaiseError(retcodeUdp);
			}
		}

		if (AppControllerBleTransmitPayload && BLE_IsConnected()) {
			if (bRptAttr)
				retcode = BLE_SendData((uint8_t*)&xdkAttrib, sizeof(xdkAttrib), NULL,
				APP_CONTROLLER_BLE_SEND_TIMEOUT_IN_MS);

			if (!notifyAttribOnly) {
				int wlen = 2; //!!skip the reserved[2] byte
				int totlen = sizeof(xdkData);
				xdkData.Len = totlen - 2;
				for (wlen = 2; wlen < totlen;) {
					int txlen =
							((totlen - wlen) > APP_CONTROLLER_BLE_TX_LEN) ?
									APP_CONTROLLER_BLE_TX_LEN : (totlen - wlen);
					retcode = BLE_SendData((((uint8_t*) &xdkData) + wlen),
							(uint8_t) txlen, NULL,
							APP_CONTROLLER_BLE_SEND_TIMEOUT_IN_MS);
					if (retcode != RETCODE_OK)
						break;

					wlen += txlen;
				}
			}

			if (cfgLogLvl < 8)
				printf("BLE Send[%d] \r\n", (int) retcode);
		}
	}

	//start noise sensor service

}



static int CfgParseValue(const char * key, char * val) {
	if (0 == strcmp(key, "SSID")) {
		strncpy(cfgWlanSsid, val, MAX_LEN_WLAN_SSID);
		printf("wlan_ssid= [%s]\n", cfgWlanSsid);
		bcfgValid = true;
		pacomCfgValid = true;
	}else if (0 == strcmp(key, "MSSID")) {
		strncpy(cfgAltWlanSsid, val, MAX_LEN_WLAN_SSID);
		printf("alt_ssid= [%s]\n", cfgAltWlanSsid);
	}else if (0 == strcmp(key, "PASSWORD")) {
		strncpy(cfgWlanPswd, val, MAX_LEN_WLAN_PASSWD);
		printf("wlan_pwd= [%s]\n", cfgWlanPswd);
	} else if (0 == strcmp(key, "UDPIP")) {
		if ( RETCODE_OK != Utils_ConvertIpStringToNumber(val, &cfgUdpIp))
			cfgUdpIp = DEST_SERVER_IP;
		printf("udp_ip= [%X]\n", (int) cfgUdpIp);
	} else if (0 == strcmp(key, "UDPPORT")) {
		cfgUdpPort = atoi(val);
		if (cfgUdpPort == 0)
			cfgUdpPort = DEST_SERVER_PORT;
		printf("udp_port= [%d]\n", cfgUdpPort);
	} else if (0 == strcmp(key, "LogLevel")) {
		cfgLogLvl = atoi(val);
		if (cfgLogLvl == 0)
			cfgLogLvl = 8;
		printf("cfgLogLvl= [%d]\n", cfgLogLvl);
	}

	return 0;
}


/**
 * @brief
 *      ThIS API uses the FAT file system library calls.
 *      This API will write and read files and it will compare the contents which has been
 *      written and read.
 * @retval
 *      RETCODE_OK - save new config and reset devcice
 *      #SDCARD_APP_ERROR - when there is a mismatch in read and write buffer
 *      #FILE_WRITE_ERROR - when file system write is failed
 *      #FILE_READ_ERROR - when file system read is failed
 */
Retcode_T ParseHttpCfg(const char * resp, char * pcfg, int blen)
{
	//TODO: Add http ssid config parse here.
	//cmpaire with cfgWlanSsid ,same do nothing
	return RETCODE_DOUBLE_INITIALIZATION;
}

Retcode_T SaveCfgAndReset(const char * httpGetResp) 
{
	Retcode_T retcode = RETCODE_OK;
	bool sdcardEject = false, status = false, sdcardInsert = false;
	printf("ReadCfgFromFileSystem \n\r");

	retcode = Storage_IsAvailable(STORAGE_MEDIUM_SD_CARD, &status);
	if ((RETCODE_OK == retcode) && (true == status)) 
	{
		char cfgBuff[BUFFER_SIZE];
		retcode = ParseHttpCfg(httpGetResp, cfgBuff, BUFFER_SIZE);
		if ( retcode != RETCODE_OK ) return retcode;
		uint16_t fileSize = strlen(cfgBuff); //BUFFER_SIZE;
		Storage_Write_T writeCredentials = { .FileName = WIFI_CONFIG_FILE_NAME,
			.WriteBuffer = httpGetResp, .BytesToWrite = fileSize,
			.ActualBytesWritten = 0UL, .Offset = 0UL, };

		retcode = Storage_Write(STORAGE_MEDIUM_SD_CARD, &writeCredentials);
		if( retcode == RETCODE_OK ) 
		{
			printf("Storage_Write writeCredentials= %s \r\n", writeCredentials.FileName);
			int i=10;
			while( i > 0 ){
				if( i&1 )
					LED_On(LED_INBUILT_RED);
				else
					LED_Off(LED_INBUILT_RED);
				vTaskDelay(pdMS_TO_TICKS(200));
			}
			BSP_Board_SoftReset();
		}
	}
	return (retcode);
}


/**
 * @brief
 *      ThIS API uses the FAT file system library calls.
 *      This API will write and read files and it will compare the contents which has been
 *      written and read.
 * @retval
 *      RETCODE_OK - All the file operations are success
 *      #SDCARD_APP_ERROR - when there is a mismatch in read and write buffer
 *      #FILE_WRITE_ERROR - when file system write is failed
 *      #FILE_READ_ERROR - when file system read is failed
 */
static Retcode_T ReadCfgFromFileSystem(void) {
	printf("ReadCfgFromFileSystem \n\r");
	//uint8_t ramBufferWrite[BUFFER_SIZE]; /* Temporary buffer for write file */
	uint8_t ramBufferRead[BUFFER_SIZE]; /* Temporary buffer for read file */
	uint16_t fileSize = BUFFER_SIZE;
	Retcode_T retcode = RETCODE_OK;
	Storage_Read_T readCredentials = { .FileName = WIFI_CONFIG_FILE_NAME,
			.ReadBuffer = ramBufferRead, .BytesToRead = fileSize,
			.ActualBytesRead = 0UL, .Offset = 0UL, };

	retcode = Storage_Read(STORAGE_MEDIUM_SD_CARD, &readCredentials);
	ramBufferRead[readCredentials.ActualBytesRead] = 0;
	printf("Storage_Read readCredentials= %s \r\n", readCredentials.FileName);
	//	printf("[%d]:{%s}\r\n", readCredentials.ActualBytesRead, ramBufferRead);
	//	char ssid[100],password[100],destip[100],destport[100];
	parseCfgCotent((char *) ramBufferRead, CfgParseValue);

	return (retcode);
}
/**
 *
 *
 * */
static Retcode_T WifiConfigFromSD() {
	printf("WifiConfigFromSD \r\n");
	Retcode_T retcode = RETCODE_OK;
	bool sdcardEject = false, status = false, sdcardInsert = false;

	retcode = Storage_IsAvailable(STORAGE_MEDIUM_SD_CARD, &status);
	if ((RETCODE_OK == retcode) && (true == status)) {
		sdcardInsert = true;
		/* Already restrict this value to be 0 or 1. */
		if (RETCODE_OK == retcode) {
			retcode = ReadCfgFromFileSystem();
		}
		printf( (RETCODE_OK == retcode) ? 
			"Write and read using FAT file system success \n\r":
			"Write and read using FAT file system failed\n\r" );

	} else {
		if (Retcode_GetCode(retcode)
				== (Retcode_T) RETCODE_STORAGE_SDCARD_UNINITIALIZED) {
			printf("\r\n SD card is not inserted in XDK\n\r");
			retcode = Storage_Enable();
		} else {
			if (true == sdcardInsert) {
				sdcardEject = true;
			}
			sdcardInsert = false;
			printf("\r\nSD card is removed from XDK\n\r");
			LED_Off(LED_INBUILT_RED);
			printf("SD card is not inserted LED indication failure XDK\n\r");
			}
	}
	if (RETCODE_OK != retcode) {
		//Retcode_RaiseError(retcode);
		//cfgWlanSsid not asigned value.
		strncpy(cfgAltWlanSsid,ALT_WLAN_SSID_DEFAULT, MAX_LEN_WLAN_SSID);
		printf("looking for ssid= [%s]\n", cfgAltWlanSsid);
		bcfgValid = true;

		strncpy(cfgWlanPswd, WLAN_PASSWORD_DEFAULT, MAX_LEN_WLAN_PASSWD);
		printf("wlan_pwd= [%s]\n", cfgWlanPswd);

		cfgUdpIp = DEST_SERVER_IP;
		printf("udp_ip= [%X]\n", (int) cfgUdpIp);

		cfgUdpPort = DEST_SERVER_PORT;
		printf("udp_port= [%d]\n", cfgUdpPort);

		cfgLogLvl = 8;
		printf("cfgLogLvl= [%d]\n", cfgLogLvl);
		retcode = RETCODE_OK ;
	}

	return retcode;
}

static SemaphoreHandle_t WlanEventSemaphore = NULL;
static SemaphoreHandle_t NetworkConfigSemaphore = NULL;
#define SCAN_INTERVAL                       (5) /**< Time interval between network scan */

#define DELAY_500_MSEC              	  UINT16_C(500)    /**< Macro used for delay function for 0,5 seconds */
#define DELAY_15_SEC                      UINT16_C(15000)  /**< Macro used for delay function for 15 seconds */
#define WLANNETWORK_EVENT_TIMEOUT         UINT32_C(200000) /**< Macro for wlan event timeout for simplelink */
bool  matchPacomSSID(const char * ssid)
{
	if( !pacomCfgValid ){

		if( strstr( ssid, cfgAltWlanSsid) != NULL )  {
			strcpy(cfgWlanSsid, ssid);
			return 1;
		}
	}
	return 0;
}

bool WaitforScan()
{
	vTaskDelay(1000);
	return TRUE;
}

static void ScanNetwork(void)
{
	printf("ScanNetwork\r\n");
    /* local variables */
    Retcode_T retcode = RETCODE_OK ;
	bool bmatch = false;
	do{
		WlanNetworkConnect_ScanInterval_T scanInterval = SCAN_INTERVAL;
    	WlanNetworkConnect_ScanList_T scanList;

		/* Turn on led before scanning*/
		LED_On(LED_INBUILT_RED);
		LED_On(LED_INBUILT_ORANGE);
		LED_On(LED_INBUILT_YELLOW);
		
		retcode = WlanNetworkConnect_ScanNetworks(scanInterval, &scanList);

		if (RETCODE_OK == retcode)
		{
			printf("\n\r[NCA] : Hey User! XDK found the following networks:\n\r");
			for (int i = 0; !bmatch && i < WLANNWCT_MAX_SCAN_INFO_BUF; i++)
			{
				if (0 != scanList.ScanData[i].SsidLength)
				{
					printf("[NCA] :  - found SSID number %d is : %s\n\r", i,
							scanList.ScanData[i].Ssid);
					static_assert((portTICK_RATE_MS != 0), "Tick rate MS is zero");
					bmatch = matchPacomSSID(scanList.ScanData[i].Ssid );
				}
			}
			printf("[NCA] : Finished scan successfully \n\r");
		}
		else if ((Retcode_T) RETCODE_NO_NW_AVAILABLE == Retcode_GetCode(retcode))
		{
			printf("[NCA] : Scan function did not found any network\n\r");
		}
		else /*(RETCODE_FAILURE == retScanStatus[0])*/
		{
			printf("[NCA] : Scan function failed [%d]\n\r", (int)retcode);
		}
		/* Turn off the led when the scan has finished and results are printed */
		LED_Off(LED_INBUILT_RED);
		LED_Off(LED_INBUILT_ORANGE);
		LED_Off(LED_INBUILT_YELLOW);
	}while(!pacomCfgValid && !bmatch && WaitforScan() );
}

void ConfirmWifiAvalibel(void)
{
    Retcode_T retcode = RETCODE_OK;
	if ((WLANNWCT_STATUS_CONNECTED == WlanNetworkConnect_GetStatus())
			&& (WLANNWCNF_IPSTATUS_IPV4_AQRD == WlanNetworkConfig_GetIpStatus()))
	{
		if (WLANNWCT_IPSTATUS_DISCT_NAQRD != WlanNetworkConnect_GetIpStatus()  &&
				(WLANNWCT_IPSTATUS_DISCT_AQRD	!= WlanNetworkConnect_GetIpStatus()))
		{
			printf("[NCA] : Wifi already connected, wait release it...\n\r");
			(void) xSemaphoreTake(WlanEventSemaphore, 0U); //Clear semaphore
			retcode = WlanNetworkConnect_Disconnect();
			if (RETCODE_OK == retcode)
			{
				xSemaphoreTake(WlanEventSemaphore, WLANNETWORK_EVENT_TIMEOUT);
			}
		}
		else
		{
			if (WLANNWCT_STATUS_DISCONNECTED == WlanNetworkConnect_GetStatus())
			{
				retcode = RETCODE_OK;
			}
		}

		printf( (RETCODE_OK == retcode) ? 
			"[NCA] : Disconnected the existing connection.\n\r" :
			"[NCA] : Disconnection has failed.\n\r"  );
	}
}

void cbDhcpIpAllocate(WlanNetworkConfig_IpStatus_T returnStatus)
{
    if (WLANNWCNF_IPSTATUS_IPV4_AQRD == returnStatus)
    {
        printf("[NCA] : Callback Function : IP was acquired using DHCP\n\r");
    }
    if (NULL != NetworkConfigSemaphore)
    {
        (void) xSemaphoreGive(NetworkConfigSemaphore);
    }
}

static Retcode_T ConnectWlan(void)
{
    /* local variables */
    WlanNetworkConfig_IpSettings_T myIpGet;
    Retcode_T retcode = RETCODE_OK;
    ConfirmWifiAvalibel();

 	(void) xSemaphoreTake(NetworkConfigSemaphore, 0U); //clear semaphore
    retcode = WlanNetworkConfig_SetIpDhcp(cbDhcpIpAllocate);
    WLANSetupInfo.SSID = cfgWlanSsid;
    WLANSetupInfo.Password = cfgWlanPswd;
    printf("\n\r[NCA] : XDK will connect to %s network.\n\r", WLANSetupInfo.SSID);
    int slReturn = -1;
    retcode = WlanNetworkConnect_PersonalWPA((WlanNetworkConnect_SSID_T)WLANSetupInfo.SSID, (WlanNetworkConnect_PassPhrase_T)WLANSetupInfo.Password);
    if (RETCODE_OK == retcode)
    {
        printf("[NCA] : Connected successfully.\n\r");
    }
    /* By default auto-connect profile is enable. Reset the profile in order to disconnect */
    slReturn = sl_WlanPolicySet(SL_POLICY_CONNECTION, SL_CONNECTION_POLICY(0, 0, 0, 0, 0), NULL, 0); /* reset policy */
    if (SL_RET_CODE_OK > slReturn)
    {
        printf("[NCA] :failed to reset connection policy\r\n");
    }

    (void) xSemaphoreTake(NetworkConfigSemaphore, WLANNETWORK_EVENT_TIMEOUT);
    retcode = WlanNetworkConfig_GetIpSettings(&myIpGet);

    if (RETCODE_OK == retcode)
    {
        printf("[NCA] :  - The DHCP IP (no callback) : %u.%u.%u.%u \n\r",
                (unsigned int) (WlanNetworkConfig_Ipv4Byte(myIpGet.ipV4, 3)),
                (unsigned int) (WlanNetworkConfig_Ipv4Byte(myIpGet.ipV4, 2)),
                (unsigned int) (WlanNetworkConfig_Ipv4Byte(myIpGet.ipV4, 1)),
                (unsigned int) (WlanNetworkConfig_Ipv4Byte(myIpGet.ipV4, 0)));
    }
    else
    {
        printf("[NCA] : WlanNetworkConfig_GetIpSettings API has failed\n\r");
    }
	return retcode;
}

/**
 *this function for get Wi-Fi info from Blegatt data
 *
 * */
static void WifiConfigFromBle(uint8_t *rxBuffer, uint8_t rxDataLength) {
	//TODO: implement wifi config from BLE
	uint8_t receiveBuffer[UINT8_C(24)];
	memset(receiveBuffer, 0, sizeof(receiveBuffer));
	memcpy(receiveBuffer, rxBuffer,
			rxDataLength < UINT8_C(24) ? rxDataLength : UINT8_C(23));
	printf("Received data: %s \n\r", receiveBuffer);

	//BSP_Board_SoftReset();
}



static void WlanConnectStatusCallback(WlanNetworkConnect_Status_T status)
{
    BCDS_UNUSED(status);
    if (NULL != WlanEventSemaphore)
    {
        (void)xSemaphoreGive(WlanEventSemaphore);
    }
}


static Retcode_T WifiConnect(){
	Retcode_T retcode = WifiConfigFromSD();
	if ( RETCODE_OK ==  retcode) 
	{
		ScanNetwork();
		ConnectWlan();;
	}
	return retcode;
}


static void Button1Callback(ButtonEvent_T buttonEvent) {
	xdkAttrib.Buttons = (xdkAttrib.Buttons & 0xFE) | ((uint8_t) !buttonEvent);
	notifyAttribOnly = true;
	if (xSemFire)	//Trigle attrib rpt
		xSemaphoreGive(xSemFire);
}

static void Button2Callback(ButtonEvent_T buttonEvent) {
	xdkAttrib.Buttons = (xdkAttrib.Buttons & 0xFD)
			| (((uint8_t) !buttonEvent) << 1);
	notifyAttribOnly = true;
	if (xSemFire)	//Trigle attrib rpt
		xSemaphoreGive(xSemFire);
}
/**
 * @brief Responsible for reading the RMS voltage of noise sensor.
 *
 * @param[in] pvParameters
 * Unused
 */
static void NoiseSensorTask(void* pvParameters) {
	printf("NoiseSensorTask \r\n");
	BCDS_UNUSED(pvParameters);

	Retcode_T retcode = RETCODE_OK;
	float rmsVoltage = 0.0f;
	static uint32_t sampleCounter = 0UL;
	static float startVal = 0.0f;
	static uint32_t avgCntr = 0UL;
	static float smoothVal = 0.0f;
	static float smoothAvgVal = 0.0f;

	while (1) {
		//vTaskDelay(100);
		retcode = NoiseSensor_ReadRmsValue(&rmsVoltage, 20U);
		//printf("NoiseSensorTask retcode == %d  rmsVoltage ==%lf \r\n", retcode,rmsVoltage);
		if (RETCODE_OK != retcode) {
			Retcode_RaiseError(retcode);
			continue;
		}

		if (sampleCounter == 0) {
			startVal = rmsVoltage;
			sampleCounter = 1;
		} else {
			if (NOISE_RMS_ADC_SAMPLES >= sampleCounter) {
				if (rmsVoltage > (startVal + NOISE_RMS_AVG_RANGE_IN_MV)) {
					/* @todo - Handle in common code noise sensor */
					smoothVal += (rmsVoltage * rmsVoltage)
							* ADC_CENTRAL_NO_OF_SAMPLES;
					//printf("smoothVal== %f \r\n",smoothVal);
					avgCntr++;
				} else if (rmsVoltage <= startVal) {
					startVal = rmsVoltage;
				}
				sampleCounter++;
			} else {
				if (avgCntr != 0) {
					smoothAvgVal = sqrt(
							smoothVal / (ADC_CENTRAL_NO_OF_SAMPLES * avgCntr));
				} else {
					smoothAvgVal = rmsVoltage;
				}
				NoiseRmsVoltage = smoothAvgVal;
				//printf("NoiseRmsVoltage== %d \r\n",NoiseRmsVoltage);
				avgCntr = 0;
				sampleCounter = 1;
				startVal = 1;
				smoothVal = 0;
			}
		}
	}
}


static void WifiConnectTask(void * vparam){
	Retcode_T retcode = RETCODE_OK;
	WlanEventSemaphore = xSemaphoreCreateBinary();
	NetworkConfigSemaphore = xSemaphoreCreateBinary();
	XDK_ASSERT( RETCODE_OK == WlanNetworkConnect_Init(WlanConnectStatusCallback) );
	int i=1000;
	while(1){
		if( (retcode = WifiConnect()) == RETCODE_OK){
			UpdRcvSvr(vparam);
		}
		vTaskDelay(i=i+i);
		if( i> 60*60000) i = 60*60000;
	}
}
/**
 * @brief To enable the necessary modules for the application
 * - WLAN
 * - UDP
 * - BLE
 * - Sensor
 *
 * @param[in] param1
 * Unused
 *
 * @param[in] param2
 * Unused
 */
void AppHttpEnable(void * param1, uint32_t param2);
static void AppControllerEnable(void * param1, uint32_t param2) {
	BCDS_UNUSED(param1);
	BCDS_UNUSED(param2);

	printf("AppControllerEnable : in \r\n");

	Storage_Enable();
	
	XDK_ASSERT( RETCODE_OK == UDP_Enable() );
	XDK_ASSERT( RETCODE_OK == BLE_Enable() );
	XDK_ASSERT( RETCODE_OK == Sensor_Enable() );
	XDK_ASSERT( RETCODE_OK == LED_Enable() );
	XDK_ASSERT( RETCODE_OK == Button_Enable() );
	XDK_ASSERT( RETCODE_OK == NoiseSensor_Enable() );

	XDK_ASSERT( pdPASS == xTaskCreate(WifiConnectTask, (const char * const ) "WifiConnect",
			TASK_STACK_SIZE_APP_CONTROLLER, NULL,TASK_PRIO_APP_CONTROLLER + 1, &WifiConnectHandle)) ;

	XDK_ASSERT( pdPASS == xTaskCreate(AppControllerFire,(const char * const ) "AppController",
				TASK_STACK_SIZE_APP_CONTROLLER, NULL,TASK_PRIO_APP_CONTROLLER, &AppControllerHandle)) ;

	XDK_ASSERT( pdPASS == xTaskCreate(NoiseSensorTask,	(const char * const ) "NoiseSensor",
					TASK_STACK_SIZE_NOISE_SENSOR, NULL,	TASK_PRIO_NOISE_SENSOR, &NoiseSensorHandle));

	AppHttpEnable(param1, param2);

	Utils_PrintResetCause();
}

/**
 * @brief To setup the necessary modules for the application
 * - WLAN
 * - UDP
 * - BLE
 * - Sensor
 *
 * @param[in] param1
 * Unused
 *
 * @param[in] param2
 * Unused
 */
static void AppControllerSetup(void * param1, uint32_t param2) {
	BCDS_UNUSED(param1);
	BCDS_UNUSED(param2);

	printf("AppControllerSetup [%s]:  \r\n", BLESetupInfo.DeviceName);
	Retcode_T retcode = Storage_Setup(&StorageSetupInfo);
	if (RETCODE_OK == retcode) {
		//		WifiConfigFromSD();
		retcode = WLAN_Setup(&WLANSetupInfo);
	}


	if (RETCODE_OK == retcode) {
		retcode = UDP_Setup(UDP_SETUP_USE_CC31XX_LAYER);
	}
	if (RETCODE_OK == retcode) {
		retcode = BLE_Setup(&BLESetupInfo);
	}
	if (RETCODE_OK == retcode) {
		SensorSetup.CmdProcessorHandle = AppCmdProcessor;
		retcode = Sensor_Setup(&SensorSetup);
	}
	retcode = LED_Setup();
	if (RETCODE_OK == retcode) {
		ButtonSetup.CmdProcessorHandle = AppCmdProcessor;
		retcode = Button_Setup(&ButtonSetup);
	}
	if (RETCODE_OK == retcode) {
		retcode = CmdProcessor_Enqueue(AppCmdProcessor, AppControllerEnable,
		NULL, UINT32_C(0));
	}
	if (RETCODE_OK == retcode) {
		retcode = NoiseSensor_Setup(NOISE_SAMPLING_FREQUENCY);
	}

	AppHttpSetup(AppCmdProcessor);

	if (RETCODE_OK != retcode) {
		printf("AppControllerSetup : Failed \r\n");
		Retcode_RaiseError(retcode);
		assert(0); /* To provide LED indication for the user */
	}
}

/* global functions ********************************************************* */

/** Refer interface header for description */
void AppController_Init(void * cmdProcessorHandle, uint32_t param2) {
	BCDS_UNUSED(param2);
	Retcode_T retcode = RETCODE_OK;
	printf("AppController_Init  \r\n");

	uint8_t lclMac[8];
	memset(&xdkAttrib, 0, sizeof(xdkAttrib));
	Utils_GetMacInfoFromNVM(UTILS_BLE_MAC_DATA, lclMac);
	memcpy(xdkAttrib.BleMac, &lclMac, 6);
	sprintf(bleDeviceName,"XDK-%02X%02X%02X%02X%02X%02X", lclMac[0],lclMac[1],\
							lclMac[2],lclMac[3],lclMac[4],lclMac[5]);
	//Utils_GetMacInfoFromNVM(UTILS_WIFI_MAC_DATA, lclMac);
	//memcpy(xdkAttrib.WifiMac, &lclMac, 6);
	xdkAttrib.Flag = 'A';
	xdkAttrib.Len = sizeof(xdkAttrib);
	BatteryMonitor_Init();

	if (cmdProcessorHandle == NULL) {
		printf("AppController_Init : Command processor handle is NULL \r\n");
		retcode = RETCODE(RETCODE_SEVERITY_ERROR, RETCODE_NULL_POINTER);
	} else {
		AppCmdProcessor = (CmdProcessor_T *) cmdProcessorHandle;
		retcode = CmdProcessor_Enqueue(AppCmdProcessor, AppControllerSetup,
		NULL, UINT32_C(0));
	}

	if (RETCODE_OK != retcode) {
		Retcode_RaiseError(retcode);
		assert(0); /* To provide LED indication for the user */
	}
}

/**@} */
/** ************************************************************************* */
